
module Yan where

import Random
--------------------------------------------------------------------------------
--                                     MAIN                                   --
--------------------------------------------------------------------------------

lancarDados dados escolha  = do
	gen <- newStdGen
	let novaEscolha = if escolha == [0,0,0,0,0]
		then [1,1,1,1,1]
		else escolha
	let dadosNovos = take 5 (randomRs (1,6) gen :: [Int])
	let novosDados = escolher novaEscolha dados dadosNovos
	return novosDados

escolher :: [Int] -> [Int] -> [Int] -> [Int]
escolher [] _ _ = []
escolher (a:as) (b:bs) (c:cs)
	| a == 0 = b : (escolher as bs cs)
	| otherwise = c : (escolher as bs cs)
--------------------------------------------------------------------------------
--                                     DADOS                                  --
--------------------------------------------------------------------------------

{---
 - Estrutura de dados responsável por representar as possíveis combinações de
 - jogo obtidas com os dados.
 --}
data Combinacao =
		UM
	| 	DOIS 
	| 	TRES
	| 	QUATRO
	| 	CINCO
	| 	SEIS
	|	TRINCA
	|	QUADRA
	|	FULL
	|	SEQMIN
	|	SEQMAX
	|	SORTE
	|	YAN
	deriving (Show, Eq)

{---
 - Estrutura de dados responsável por representar as possíveis combinações de
 - somatório.
 --}	
data CombinacaoSomatorio = 
		BONUS
	|	TOTAL1
	|	TOTAL2
	deriving (Show, Eq)	

{---
 - Estrutura de dados responsável por representar os categorias de jogo.
 --}
data Categoria = 
		SUBIDA
	|	DESCIDA
	|	LIVRE
	|	SECO
	deriving (Show, Eq)
	
type Celula = (Combinacao,Int)
type Coluna = [Celula]
type Tabela	= [(Categoria,Coluna)]
type Dado = Int
type Dados = [Dado]

type CelulaSomatorio = (CombinacaoSomatorio,Int)
type ColunaSomatorio = [CelulaSomatorio]
type TabelaSomatorio = [(Categoria, ColunaSomatorio)]
type Somatorios = (Int, TabelaSomatorio)

colunaLimpa :: Coluna
colunaLimpa = [(UM, -1),(DOIS, -1), (TRES, -1), (QUATRO, -1), (CINCO, -1),
			 (SEIS, -1), (TRINCA, -1), (QUADRA, -1), (FULL, -1), (SEQMIN, -1),
			 (SEQMAX, -1), (SORTE, -1), (YAN, -1)]
			 
colunaIndisponivel = [(UM, 0),(DOIS, 0), (TRES, 0), (QUATRO, 0), (CINCO, 0),
			 (SEIS, 0), (TRINCA, 0), (QUADRA, 0), (FULL, 0), (SEQMIN, 0),
			 (SEQMAX, 0), (SORTE, 0), (YAN, 0)]
			
tabelaLimpa :: Tabela
tabelaLimpa = [(DESCIDA, colunaLimpa), (SUBIDA, colunaLimpa),
			(LIVRE, colunaLimpa), (SECO, colunaLimpa)]

tabelaIndisponivel :: Tabela
tabelaIndisponivel = [(DESCIDA, colunaIndisponivel),
	(SUBIDA, colunaIndisponivel), (LIVRE, colunaIndisponivel),
	(SECO, colunaIndisponivel)]

--------------------------------------------------------------------------------
--                                   FUNÇÕES                                  --
--------------------------------------------------------------------------------
jogar_dado = 5

bonusTRINCA :: Int
bonusTRINCA = 15

bonusQUADRA :: Int
bonusQUADRA = 20

bonusFULL :: Int
bonusFULL = 30

bonusSEQ :: Int
bonusSEQ = 40

bonusYAN :: Int
bonusYAN = 50

fazerTabela :: Coluna -> Coluna -> Coluna -> Coluna -> Tabela
fazerTabela colunaDescida colunaSubida colunaLivre colunaSeco =
	[(DESCIDA, colunaDescida),
	 (SUBIDA, colunaSubida),
	 (LIVRE, colunaLivre),
	 (SECO, colunaSeco)]

{---
 - fazerColuna(um, dois, tres, quatro, cinco, seis, trinca, quatra, full, 
 				seqmin, seqmax, sorte, yan)
 -   *: cada parâmetro representa os valores de suas respectivas combinações em
 - 		uma dada categoriar
 - retorna uma coluna em uma dada categoria
 -
 - Função cria uma coluna com os valores passados para todas as combinações em
 - uma dada categoria.
 --}
 
isTabelaDisponivelSemSeco :: Tabela -> Bool
isTabelaDisponivelSemSeco tabela = tabelaDisponivelSemSeco (gerarTabelaDisponivel tabela 3)
 
tabelaDisponivelSemSeco ::  Tabela -> Bool
tabelaDisponivelSemSeco [] = False
tabelaDisponivelSemSeco ((cat,col):as) = colunaDisponivelSemSeco col ||
	tabelaDisponivelSemSeco as
 	
colunaDisponivelSemSeco :: Coluna -> Bool
colunaDisponivelSemSeco [] = False
colunaDisponivelSemSeco ((com,val):as) = val == 1 || colunaDisponivelSemSeco as 	

fazerColuna :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int ->
				Int -> Int -> Int -> Int -> Coluna
fazerColuna um dois tres quatro cinco seis trinca quadra full seqmin seqmax
			sorte yan = [(UM, um), (DOIS, dois), (TRES, tres), (QUATRO, quatro),
			(CINCO, cinco), (SEIS, seis), (TRINCA, trinca), (QUADRA, quadra),
			(FULL, full), (SEQMIN, seqmin), (SEQMAX, seqmax), (SORTE, sorte),
			(YAN, yan)]

gerarTabelaDisponivel :: Tabela -> Int -> Tabela
gerarTabelaDisponivel [(DESCIDA,colDes),(SUBIDA, colSub), (LIVRE, colLiv),
	(SECO, colSec)] jogada = (DESCIDA, (gerarDESCIDADisponivel colDes)) :
	(SUBIDA, (gerarSUBIDADisponivel colSub)) :
	(LIVRE, (gerarLIVREDisponivel colLiv)) :
	(SECO, (gerarSECODisponivel colSec jogada)) : []
	
gerarDESCIDADisponivel :: Coluna -> Coluna
gerarDESCIDADisponivel ((UM, val):as)
	| val == -1 = (UM, 1) : gerarDESCIDADisponivel2 ((UM, val):as)
	| otherwise = (UM, 0) : gerarDESCIDADisponivel2 ((UM, val):as)

gerarDESCIDADisponivel2 :: Coluna -> Coluna
gerarDESCIDADisponivel2 [_] = []
gerarDESCIDADisponivel2 ((_,val1):(com,val2):as)
	| val1 /= -1 && val2 == -1 = (com, 1) : gerarDESCIDADisponivel2 ((com,val2):as)
	| otherwise = (com, 0) : gerarDESCIDADisponivel2 ((com,val2):as)
	
gerarSUBIDADisponivel :: Coluna -> Coluna
gerarSUBIDADisponivel [(com,val)]
	| val == -1 = [(com, 1)]
	| otherwise = [(com, 0)]
	
gerarSUBIDADisponivel ((com1,val1):(com2,val2):as)
	| val2 /= -1 && val1 == -1 = (com1, 1) : gerarSUBIDADisponivel ((com2,val2):as)
	| otherwise =  (com1, 0) : gerarSUBIDADisponivel ((com2,val2):as)
	
gerarLIVREDisponivel :: Coluna -> Coluna
gerarLIVREDisponivel [] = []
gerarLIVREDisponivel ((com,val):as)
	| val == -1 = (com, 1) : gerarLIVREDisponivel as
	| otherwise = (com, 0) : gerarLIVREDisponivel as

gerarSECODisponivel :: Coluna -> Int -> Coluna
gerarSECODisponivel [] _ = []
gerarSECODisponivel ((com,val):as) jogada
	| jogada == 1 && val == -1 = (com, 1) : gerarSECODisponivel as jogada
	| otherwise = (com, 0) : gerarSECODisponivel as jogada

gerarSomatorios :: Tabela -> Somatorios
gerarSomatorios tabela = (somarTabelaSomatorio (gerarTabelaSomatorio tabela),
	gerarTabelaSomatorio tabela)  
	
somarTabelaSomatorio :: TabelaSomatorio -> Int
somarTabelaSomatorio [] = 0
somarTabelaSomatorio ((cat,col):as) = somarColunaSomatorio col +
	somarTabelaSomatorio as
	
somarColunaSomatorio :: ColunaSomatorio -> Int
somarColunaSomatorio [] = 0
somarColunaSomatorio ((com,val):as)
	| val == -1 = somarColunaSomatorio as
	| otherwise = val + somarColunaSomatorio as
			
gerarTabelaSomatorio :: Tabela -> TabelaSomatorio
gerarTabelaSomatorio [] = [] 
gerarTabelaSomatorio ((cat,col):as) = (cat, gerarColunaSomatorio col) : 
	gerarTabelaSomatorio as
	
gerarColunaSomatorio :: Coluna -> ColunaSomatorio
gerarColunaSomatorio col = [(BONUS, getBonus col), (TOTAL1, getTotal1 col),
	(TOTAL2, (getTotal col) - (getTotal1 col))] 

getBonus :: Coluna -> Int
getBonus [(UM, um), (DOIS, dois), (TRES, tres), (QUATRO, quatro),(CINCO, cinco),
			(SEIS, seis), _, _, _, _, _, _,	_]
	| um == -1 || dois == -1 || tres == -1 || quatro == -1 || cinco == -1 ||
	  seis == -1 =  -1
	| um == 0 || dois == 0 || tres == 0 || quatro == 0 || cinco == 0 || 
	  seis == 0 = 0
	| otherwise = 30

getTotal1 :: Coluna -> Int
getTotal1 ((TRINCA,_):as) = 0
getTotal1 ((com,val):as)
	| val == -1 = getTotal1 as
	| otherwise = val + getTotal1 as
	
getTotal :: Coluna -> Int
getTotal [] = 0
getTotal ((com,val):as)
	| val == -1 = getTotal as
	| otherwise = val + getTotal as
	
{---
 - marcar(tabela, dados, nJogada, categoria, combinacao)
 -   tabela: representa a situação atual do jogo;
 -   dados: representa a jogada atual
 -   nJogada: representa se a jogada atual é a 1ª, 2ª ou 3ª
 -   categoria: categoria escolhida para marcar na tabela
 -   combinacao: combinação escolhida para marcar na categoria escolhida
 - retorna a tabela atualizada
 -
 - Função busca a categoria e combinação na tabela, checando a disponibilidade
 - da célula escolhida e atualizando a tabela com a avaliação dos dados.
 --}
marcar :: Tabela -> Dados -> Int -> Categoria -> Combinacao -> Tabela
marcar ((cat,col):as) dados nJogada categoria combinacao
	| not (checar ((cat,col):as) nJogada categoria combinacao) = error 
		"Combinacao indisponivel para a Categoria dada"
	| cat == categoria = (cat, marcarColuna col dados combinacao) :	as
	| otherwise = (cat,col) : marcar as dados nJogada categoria combinacao 

{---
 - checar(tabela, nJogada, categoria, combinacao)
 -   tabela: representa a situação atual do jogo;
 -   nJogada: representa se a jogada atual é a 1ª, 2ª ou 3ª
 -   categoria: categoria escolhida para marcar na tabela
 -   combinacao: combinação escolhida para marcar na categoria escolhida
 - retorna se a célula escolhida está disponível para atualizações.
 -
 - Função busca a categoria e combinação na tabela, checando a disponibilidade
 - da célula escolhida.
 --}
checar :: Tabela -> Int -> Categoria -> Combinacao -> Bool
checar ((cat,col):as) nJogada categoria combinacao
	| cat == categoria && cat == LIVRE = checarLIVRE col combinacao
	| cat == categoria && cat == SECO = checarSECO col nJogada combinacao
	| cat == categoria && cat == SUBIDA = checarSUBIDA col combinacao
	| cat == categoria && cat == DESCIDA = checarDESCIDA col combinacao
	| otherwise = checar as nJogada categoria combinacao

{---
 - checarLIVRE(coluna, combinacao)
 -   coluna: representa todas as combinações possíveis para a categoria LIVRE
 -   combinacao: representa a combinacao escolhida para atualização
 - retorna se a célula escolhida está disponível para atualizações.
 -
 - Função busca a combinação na coluna e checa se a célula escolhida não foi já
 - marcada.
 --}
checarLIVRE :: Coluna -> Combinacao -> Bool
checarLIVRE [] _ = True
checarLIVRE ((com,valor) : as) combinacao
	| com == combinacao && valor /= -1 = False
	| otherwise = checarLIVRE as combinacao

{---
 - checarSECO(coluna, nJogada, combinacao)
 -   coluna: representa todas as combinações possíveis para a categoria SECO
 -   nJogada: representa se a jogada atual é a 1ª, 2ª ou 3ª
 -   combinacao: representa a combinacao escolhida para atualização
 - retorna se a célula escolhida está disponível para atualizações.
 -
 - Função busca a combinação na coluna e checa se a célula escolhida não foi já
 - marcada e se o jogador está na primeira jogada de sua rodada.
 --}
checarSECO :: Coluna -> Int -> Combinacao -> Bool
checarSECO [] _ _ = True
checarSECO ((com,valor):as) nJogada combinacao
	| nJogada /= 1 = False
	| com == combinacao && valor /= -1 = False
	| otherwise = checarSECO as nJogada combinacao
	
{---
 - checarDESCIDA(coluna, combinacao)
 -   coluna: representa todas as combinações possíveis para a categoria DESCIDA
 -   combinacao: representa a combinacao escolhida para atualização
 - retorna se a célula escolhida está disponível para atualizações.
 -
 - Função busca a combinação na coluna e checa se a célula escolhida não foi já
 - marcada e se a combunação que a prescede já foi marcada.
 --}
checarDESCIDA :: Coluna -> Combinacao -> Bool
checarDESCIDA [_] _ = True
checarDESCIDA ((com,valor):as) combinacao
	| com == combinacao && valor == -1 = True
checarDESCIDA ((_,valorA):(com,valor):as) combinacao
	| valorA == -1 = False
	| com == combinacao && valor /= -1 = False
	| otherwise = checarDESCIDA ((com,valor):as) combinacao

{---
 - checarSUBIDA(coluna, combinacao)
 -   coluna: representa todas as combinações possíveis para a categoria SUBIDA
 -   combinacao: representa a combinacao escolhida para atualização
 - retorna se a célula escolhida está disponível para atualizações.
 -
 - Função busca a combinação na coluna e checa se a célula escolhida não foi já
 - marcada e se a combunação que a sucede já foi marcada.
 --}
checarSUBIDA :: Coluna -> Combinacao -> Bool
checarSUBIDA [(com, valor)] combinacao
	| com == combinacao && valor == -1 = True
	| otherwise = False
checarSUBIDA ((com,valor):(comP,valorP):as) combinacao
	| com == combinacao && valorP == -1 = False
	| com == combinacao && valor /= -1 = False
	| com == combinacao = True
	| otherwise = checarSUBIDA ((comP,valorP):as) combinacao

{---
 - marcarColuna(coluna, dados, combinacao)
 -   coluna: representa todas as combinações possíveis em alguma categoria
 -   dados: representa a jogada atual
 -   combinacao: representa a combinacao escolhida para atualização
 - retorna a coluna atualizada
 -
 - Função busca a combinação na coluna, atualizando esta com a avaliação dos
 - dados.
 --}
marcarColuna :: Coluna -> Dados -> Combinacao -> Coluna
marcarColuna  ((com,valor):as) dados combinacao
	| com == combinacao = avaliar dados combinacao : as
	| otherwise = (com,valor) : marcarColuna as dados combinacao

{---
 - avaliar(dados, combinacao)
 -   dados: representa a jogada atual
 -   combinacao: representa a combinacao escolhida para atualização
 - retorna a célula atualizada 
 - 
 - Função responsável por avaliar o resultado do dados para uma determinada
 - combinação.  
 --}
avaliar :: Dados -> Combinacao -> Celula
avaliar dados UM  = (UM, avaliarUM dados)
avaliar dados DOIS = (DOIS, avaliarDOIS dados)
avaliar dados TRES = (TRES, avaliarTRES dados)
avaliar dados QUATRO = (QUATRO, avaliarQUATRO dados)
avaliar dados CINCO = (CINCO, avaliarCINCO dados)
avaliar dados SEIS = (SEIS, avaliarSEIS dados)
avaliar dados TRINCA = (TRINCA, avaliarTRINCA dados)
avaliar dados QUADRA = (QUADRA, avaliarQUADRA dados)
avaliar dados FULL = (FULL, avaliarFULL dados)
avaliar dados SEQMIN = (SEQMIN, avaliarSEQMIN dados)
avaliar dados SEQMAX = (SEQMAX, avaliarSEQMAX dados)
avaliar dados SORTE = (SORTE, avaliarSORTE dados)
avaliar dados YAN = (YAN, avaliarYAN dados)

{---
 - avaliarNumero(x, dados)
 -   x: representa um valor do dado
 -   dados: representa a jogada atual
 - retorna a avaliação de uma das 6 avaliações numéricas
 - 
 - Função avaliar o número de vezes que o valor x é apresentado nos dadaos,
 - retornando sua soma.
 --}
avaliarNumero :: Int -> Dados -> Int
avaliarNumero _ [] = 0
avaliarNumero x (a:as)
	| x == a = x + avaliarNumero x as
	| otherwise = avaliarNumero x as

{---
 - avaliarUM(dados)
 -   dados: representa a jogada atual
 - retorna a avaliação para a categoria UM
 - 
 - Função avaliar o número de vezes que o o valor 1 é apresentado nos dadaos,
 - retornando sua soma.
 --}
avaliarUM :: Dados -> Int
avaliarUM dados
	| avaliarNumero 1 dados >= 2 = avaliarNumero 1  dados
	| otherwise = 0

{---
 - avaliarDOIS(dados)
 -   dados: representa a jogada atual
 - retorna a avaliação para a categoria DOIS
 - 
 - Função avaliar o número de vezes que o o valor 2 é apresentado nos dadaos,
 - retornando sua soma.
 --}
avaliarDOIS :: Dados -> Int
avaliarDOIS dados
	| avaliarNumero 2 dados >= 4 = avaliarNumero 2 dados
	| otherwise = 0

{---
 - avaliarTRES(dados)
 -   dados: representa a jogada atual
 - retorna a avaliação para a categoria TRES
 - 
 - Função avaliar o número de vezes que o o valor 3 é apresentado nos dadaos,
 - retornando sua soma.
 --}
avaliarTRES :: Dados -> Int
avaliarTRES dados
	| avaliarNumero 3 dados >= 9 = avaliarNumero 3 dados
	| otherwise = 0

{---
 - avaliarQUATRO(dados)
 -   dados: representa a jogada atual
 - retorna a avaliação para a categoria QUATRO
 - 
 - Função avaliar o número de vezes que o o valor 4 é apresentado nos dadaos,
 - retornando sua soma.
 --}
avaliarQUATRO :: Dados -> Int
avaliarQUATRO dados
	| avaliarNumero 4 dados >= 12 = avaliarNumero 4 dados
	| otherwise = 0 

{---
 - avaliarCINCO(dados)
 -   dados: representa a jogada atual
 - retorna a avaliação para a categoria CINCO
 - 
 - Função avaliar o número de vezes que o o valor 5 é apresentado nos dadaos,
 - retornando sua soma.
 --}
avaliarCINCO :: Dados -> Int
avaliarCINCO dados
	| avaliarNumero 5 dados >= 15 = avaliarNumero 5 dados
	| otherwise = 0

{---
 - avaliarSEIS(dados)
 -   dados: representa a jogada atual
 - retorna a avaliação para a categoria SEIS
 - 
 - Função avaliar o número de vezes que o o valor 6 é apresentado nos dadaos,
 - retornando sua soma.
 --}
avaliarSEIS :: Dados -> Int
avaliarSEIS dados
	| avaliarNumero 6 dados >= 18 = avaliarNumero 6 dados
	| otherwise = 0

{---
 - avaliarTRINCA(dados)
 -   dados: representa a jogada atual
 - retorna a avaliação para a categoria TRINCA
 - 
 - Função verifica se existe algum valor apresentado nos dados que se repete
 - pelo menos 3 vezes, somando os três valores ao bonusTRINCA.
 --}
avaliarTRINCA :: Dados -> Int
avaliarTRINCA dados
	| repeticao dados 3 /= 0 = (repeticao dados 3) * 3 + bonusTRINCA
	| repeticao dados 4 /= 0 = (repeticao dados 4) * 3 + bonusTRINCA
	| repeticao dados 5 /= 0 = (repeticao dados 5) * 3 + bonusTRINCA
	| otherwise = 0

{---
 - avaliarQUADRA(dados)
 -   dados: representa a jogada atual
 - retorna a avaliação para a categoria QUADRA
 - 
 - Função verifica se existe algum valor apresentado nos dados que se repete
 - pelo menos 4 vezes, somando os quatro valores ao bonusQUADRA.
 --}
avaliarQUADRA :: Dados -> Int
avaliarQUADRA dados
	| repeticao dados 4 /= 0 = (repeticao dados 4) * 4 + bonusQUADRA
	| repeticao dados 5 /= 0 = (repeticao dados 5) * 4 + bonusQUADRA
	| otherwise = 0	

{---
 - avaliarFULL(dados)
 -   dados: representa a jogada atual
 - retorna a avaliação para a categoria FULL
 - 
 - Função verifica se existe algum valor apresentado nos dados que se repete
 - 3 vezes e outro valor que se repete 2 vezes, somando os cinco valores ao
 - bonusFULL.
 --}
avaliarFULL :: Dados -> Int
avaliarFULL dados
	| repeticao dados 3 /= 0 && repeticao dados 2 /= 0 = 
		(repeticao dados 3) * 3 + (repeticao dados 2) * 2 + bonusFULL
	| repeticao dados 5 /= 0 = (repeticao dados 5) * 5 + bonusFULL
	| otherwise = 0

{---
 - avaliarSEQMIN(dados)
 -   dados: representa a jogada atual
 - retorna a avaliação para a categoria SEQMIN
 - 
 - Função verifica se existe alguma combinação entre os resultados dos dados com
 - os valores 1,2,3,4,5, somando os cinco valores ao bonusSEQMIN.
 --}
avaliarSEQMIN :: Dados -> Int
avaliarSEQMIN dados
	| elem 1 dados && elem 2 dados && elem 3 dados && elem 4 dados &&
		elem 5 dados = somaDados dados + bonusSEQ
	| otherwise = 0

{---
 - avaliarSEQMAX(dados)
 -   dados: representa a jogada atual
 - retorna a avaliação para a categoria SEQMAX
 - 
 - Função verifica se existe alguma combinação entre os resultados dos dados com
 - os valores 2,3,4,5,6 somando os cinco valores ao bonusSEQMAX.
 --}
avaliarSEQMAX :: Dados -> Int
avaliarSEQMAX dados
	| elem 2 dados && elem 3 dados && elem 4 dados && elem 5 dados &&
		elem 6 dados = somaDados dados + bonusSEQ
	| otherwise = 0

{---
 - avaliarSORTE(dados)
 -   dados: representa a jogada atual
 - retorna a avaliação para a categoria SORTE
 - 
 - Função apenas soma os cinco valores dos dados.
 --}		
avaliarSORTE :: Dados -> Int
avaliarSORTE dados = somaDados dados		

{---
 - avaliarYAN(dados)
 -   dados: representa a jogada atual
 - retorna a avaliação para a categoria YAN
 - 
 - Função verifica se existe algum valor apresentado nos dados que se repete
 - 5 vezes, somando os cinco valores ao bonusYAN.
 --}		
avaliarYAN :: Dados -> Int
avaliarYAN dados
	| repeticao dados 5 /= 0 = (repeticao dados 5) * 5 + bonusYAN
	| otherwise = 0		

{---
 - repeticao(dados,nRepeticoes)
 -   dados: representa a jogada atual
 -   nRepeticoes: representa o número de repetições desejadas
 - retorna o elemento que se repete n vezes
 - 
 - Função que busca o elemento que se repete nReticoes vezes, retornando 0 caso
 - não encontre nenhum elemento.
 --}
repeticao :: Dados -> Int -> Int
repeticao [] _ = 0
repeticao (a:as) nRepeticoes
	| numeroRepeticoes (a:as) a == nRepeticoes = a
	| otherwise = repeticao (removerDados as a) nRepeticoes 

{---
 - numeroRepeticoes(dados,x)
 -   dados: representa a jogada atual
 -   x: um elemento qualquer
 - retorna quantas vezes x aparece em dados
 - 
 - Função o número de vezes que o elemento x aparece em dados.
 --}
numeroRepeticoes :: Dados -> Int -> Int
numeroRepeticoes dados x = length [y | y <- dados, y == x]

{---
 - removerDados(dados,x)
 -   dados: representa a jogada atual
 -   x: um elemento qualquer
 - retorna todos os dados que não apresentam o valor x
 - 
 - Função que remove todas apacições de x em dados.
 --}
removerDados :: Dados -> Int -> Dados
removerDados [] _ = []
removerDados (a:as) x
	| a == x = removerDados as x
	| otherwise = a : removerDados as x

{---
 - somaDados(dados)
 -   dados: representa a jogada atual
 - retorna a soma de todos os dados
 - 
 - Função que soma todos os valores dos dados.
 --}	
somaDados :: Dados -> Int
somaDados dados = foldl (+) 0 dados	

{---
 - stringToInt(string)
 -   string: String a ser convertida
 - retorna a representação inteira da string passada
 -
 - Função que converte uma String em um inteiro. A string "" será convertiva em
 - -1.
 --}
stringToInt :: String -> Int
stringToInt string
	| string == "" = (-1)
	| otherwise = read string::Int

{---
 - intToString(int)
 -   int: inteiro a ser convertido
 - retorna a representação string do inteiro passado
 -
 - Função que converte um inteiro em uma String. O inteiro -1 será convertido
 - na string "".
 --}	
intToString :: Int -> String
intToString int
	| int == (-1) = ""
	| otherwise = (show int)  